/*
Flexperimentos.
Copyright (C) 2007  Richard R Manzke

This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
*/
package flexperimentos.validators
{
	import mx.validators.Validator;
	import mx.validators.ValidationResult;

	
	/**
	 * CPFValidator
	 * @author Richard R Manzke <tuco.net@gmail.com>
	 * @langversion ActionScript 3.0
	 */
	public class CPFValidator extends Validator 
	{
		private var results:Array;
		private const CPF_LENGTH:int = 11;
		
		public function CPFValidator(){
			super();
		}
		
		override protected function doValidation(value:Object):Array{
			var cpf:Number = Number(value);
			results = [];
			
			// Super classe é chamada para verificação de campo requerido.
			results = super.doValidation(value);
			if (results.length > 0)
				return results;
				
			// Verifica se o CPF é um número.
			if (isNaN(cpf) ){
				results.push(new ValidationResult(true, null, "NaN", "O CPF não é um número."));
				return results;
			}
			
			// Verifica se o CPF tem comprimento correto.
			if (cpf.toString().length != CPF_LENGTH && value){
				results.push(new ValidationResult(true, null, "invalido", "O CPF tem tamanho inválido."));
				return results;
			}
			
			// Confere os dígitos verificadores
			if (!ConfereDigitos(cpf) && value){
				results.push(new ValidationResult(true, null, "Invalido", "O CPF é inválido!"));				
				return results;
			}
			return results;
		}
		
		/**
		 * Confere os digitos verificadores de um CPF.
		 * @param nrCPF Número do CPF
		 * @return O valor retornado será <code>true</code> se a verificação de digitos for verdadeira;
		 */
		private function ConfereDigitos(nrCPF:Number):Boolean{
			
			if (nrCPF.toString().length != CPF_LENGTH)
				return false;
			
			var cpf:String = nrCPF.toString();
			var multiplicador:Array = [10,9,8,7,6,5,4,3,2];
			var digito1:Number = Number(cpf.charAt(9));
			var digito2:Number = Number(cpf.charAt(10));
			var r:Number = 0;
			
			// Calculo do primeiro digito
			for (var i:int = 0; i < multiplicador.length; i++){
				r += Number(cpf.charAt(i)) * multiplicador[i];
				multiplicador[i] += 1;
			}
			r %= 11;
			r = r < 2 ? 0 : 11 - r;
			if (r != digito1)
				return false;
				
			// Calculo do segundo digito
			multiplicador.push(2);
			r = 0;
			for (i = 0; i < multiplicador.length; i++){
				r += Number(cpf.charAt(i)) * multiplicador[i];
			}
			r %= 11;
			r = r < 2 ? 0 : 11 - r;
			if (r == digito2)
				return true;
			else
				return false;
		}
	}
}